# actors view

import os

import pyglet
from pyglet.gl import *
from pyglet.image import Animation, AnimationFrame, load

import cocos
from cocos.director import director
from cocos.cocosnode import CocosNode
from cocos.sprite import Sprite
from cocos.actions import Show, Hide

from squirtle_mod import squirtle_cocos_adaptor as sqa

import gg

class VActorMix(object):
    """
    Responsabilities:
        accept params from model, both for creation and update

    Note that we blindly add members from the dicts send by the model.
    """    

    # 
    data_for_subtype = { # subtype:(base_fname, offset,...)
        'brownbird':('bratac_Bird', (0.0, 0.0))
        }

    def __init__(self,worldview, info_creation, info_update):
        self.worldview = worldview
        for key in info_creation:
            setattr(self, key, info_creation[key])
        self.update_from_model(info_update)
        self.init2()

    def init2(self):
        # override this to complete __init__ in the subclass without overriding
        # init.
        # also, here is the point to call the __init__ for the cocos mixed class
        # warn: be carefull with values received from model that will be trashed
        # by the call to CocosNode ctor , like position
        # VActorBaseMixin.init2 promises to do nothing, so subclass will not
        # need to override him
        pass

    def update_from_model(self, info_update):
        for key in info_update:
            setattr(self, key, info_update[key])

    def scale_for_image(self, raw_image_width):
        # we want
        # <normalized width> == < view_object width>/<view viewport width>
        # and we know <view_object width> = scale*<raw_img_width>
        # so scale = <normalized witdh>*<view viewport width>/<raw_image_width>
        scale = self.normalized_width*self.worldview.unzoomed_viewport_width/raw_image_width
        return scale

    def prepare_media(self): # prepare animation ?
        """
        responsabilities:
            set the host scale to comply with the desided relative width.
            May load/parametrize conditionally, accounting for screen size or
            config parameters 
        """
        pass


class VBird(VActorMix, sqa.SVGnode):
    data_for_subtype = { # subtype:(base_fname, offset,...)
        'brownbird':('bratac_Bird', (0.0, 0.0))
        }
    def init2(self):
        short_fname, delta_anchor = data_for_subtype[self.subtype]
        fname = gg.actors_dir
        #? TODO: set scale factor
        # remember to tmp save any member that the following call will trash
        # and restore later
        position = self.position
        super(sqa.SVGnode).__init__(fname)
        self.position = position
        self.anchor += delta_anchor # displace the leg height
        self.parent_name = 'svg' # wanted plane

    def on_enter(self):
        super(VBird,self).on_enter()
        self.scale = 1.0 #(2*self.wr)/self.fheight


class VPigeon(VActorMix, sqa.SVGnode):
    data_for_subtype = { # subtype:(base_fname, 
        'brownbird':('yyycatch_chick', (0.0, 0.0))
        }
    def init2(self):
        self.parent_name = 'svg' # wanted plane

##    def on_enter(self):
##        super(VPigeon,self).on_enter()
##        self.scale = 1.0#(2*self.wr)/self.fheight

        
class VExit(VActorMix, sqa.SVGnode):
    def init2(self):
        self.parent_name = 'svg' # wanted plane

    def on_enter(self):
        super(VExit,self).on_enter()
        self.scale = (2*self.wr)/self.fheight

# bg - terrain actors (sprite)
class VTerrainBitmap(VActorMix, Sprite):
    def init2(self):
        levels_dir = self.worldview.get_dir('levels')
        if gg.use_svg_bg:
            fname = os.path.join(levels_dir, '%02d.svgz'%self.stage)
        else:
            fname = os.path.join(levels_dir, '%02d.jpg'%self.stage)
        image = load(fname) # pyglet.image.load
        position = self.position
        Sprite.__init__(self,image, position=self.position,
                                             anchor=(0,0))
        self.position=position
        self.parent_name = 'bg' # wanted plane

# goal_line actor ( geometry )
class VGoalLine(VActorMix, CocosNode):
    def init2(self):
        # remember to tmp save any member that the super call will trash
        # and restore later
        position = self.position
        CocosNode.__init__(self)
        self.position = position
        self.parent_name = 'goal_line' # wanted plane

    def on_enter(self):
        super(VGoalLine,self).on_enter()
        self.prepare_media()

    def prepare_media(self):
#        self.scale = self.scale_for_image(self.normalized_width)
#        self.scale = self.scale_for_image(self.normalized_width)
        r = 4#self.normalized_width/2.0
        self.vertexes = [
            (-r, self.min_y),(+r, self.min_y), # quad1 , bottom fail zone
            (+r, self.max_y),(-r, self.max_y)
            ]
        
    def draw(self):
        glPushMatrix()
        self.transform()
        glColor4ub(255,0,0,255)
        glBegin(GL_QUADS)
        for p in self.vertexes:
            glVertex2f(*p)
        glEnd()        
        glPopMatrix()

class VGoalZone(VActorMix, CocosNode):
    def init2(self):
        # remember to tmp save any member that the super call will trash
        # and restore later
        position = self.position
        CocosNode.__init__(self)
        self.position = position
        self.parent_name = 'goal_line+' # wanted plane, one above goal_line

    def on_enter(self):
        super(VGoalZone,self).on_enter()
        self.prepare_media()

    def prepare_media(self):
#        self.scale = self.scale_for_image(self.normalized_width)
#        self.scale = self.scale_for_image(self.normalized_width)
        r = 4#self.normalized_width/2.0
        self.vertexes = [
            (-r, self.min_y),(+r, self.min_y),
            (+r, self.max_y),(-r, self.max_y)
            ]
        
    def draw(self):
        glPushMatrix()
        self.transform()
        glColor4ub(255,0,255,255)
        glBegin(GL_QUADS)
        for p in self.vertexes:
            glVertex2f(*p)
        glEnd()        
        glPopMatrix()


# pigeons exit actor : puede ser un sistema departiculas solo, o acompaniado
# de una imagen, digamos la de casita duende o un nido.

class VPointInPos(VActorMix, CocosNode):
    data_for_subtype = { # subtype:color4
        'brownbird':( 255,0,0,255 ),
        'in_play':( 255,0,255,255 )
        }
    def init2(self):
        # remember to tmp save any member that the super call will trash
        # and restore later
        position = self.position
        CocosNode.__init__(self)
        self.position = position
        self.parent_name = 'goal_line' # wanted plane

    def on_enter(self):
        CocosNode.on_enter(self)
        self.prepare_media()

    def prepare_media(self):
        self.color = self.data_for_subtype[self.subtype]
        self.vertexes = [(0, 0)]

    def draw(self):
        glPushMatrix()
        self.transform()
        glColor4ub(*self.color)
        glPointSize(10.0)
        glBegin(GL_POINTS)
        glVertex2f(0.1, 0.1)
        glEnd()            
        glPopMatrix()

class VSquare(VActorMix, CocosNode):
    data_for_subtype = { # subtype:color4
        'player1':( 255,0,0,200 ),
        'player2':( 0,0,255,200 ),
        }
    def init2(self):
        # remember to tmp save any member that the following call will trash
        # and restore later
        position = self.position
        CocosNode.__init__(self)
        self.position = position
        print 'subtype, position:', self.subtype, position
        self.parent_name = 'goal_line' # wanted plane

    def on_enter(self):
        CocosNode.on_enter(self)
        self.prepare_media()

    def prepare_media(self):
        self.color = self.data_for_subtype[self.subtype]
        width = self.normalized_width
        r = width/2.0
        self.vertexes = [(r, r),(r, -r),(-r, -r),(-r,r)]
        self.scale = self.scale_for_image(width)

    def draw(self):
        glPushMatrix()
        self.transform()
        glBegin(GL_QUADS)
        glColor4ub( *self.color )
        for v in self.vertexes:
            glVertex2f(*v)
        glEnd()
        glPopMatrix()

cls_from_atype = {
    'bird':VSquare,#:VBird,
    'pigeon':VSquare,#VPigeon,
    'exit':VExit,
    'goal_line':VGoalLine,#VPointInPos
    'goal_zone':VGoalZone,
    'pusher_line':VGoalLine,
    'terrain':VTerrainBitmap
    }



# TODO: allow terrain to be an svg - no time!
def View_objs_Factory(worldview, info_creation, info_update):
    atype = info_creation['atype']
    #print 'view factory - atype, info creation:',atype, info_creation
    return cls_from_atype[atype](worldview, info_creation, info_update)    
    
 
